package com.fc.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fc.anno.Desensitize;
import com.fc.enums.DesensitizeType;
import com.fc.utils.DesensitizeUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Objects;
import java.util.function.UnaryOperator;
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DesensitizeJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private DesensitizeType type;
    private int prefixLen;
    private int suffixLen;
    private String mask;

    /* 策略表：DesensitizeType → 函数 */
    private static final EnumMap<DesensitizeType, UnaryOperator<String>> STRATEGY = new EnumMap<>(DesensitizeType.class);

    static {
        STRATEGY.put(DesensitizeType.NAME, DesensitizeUtil::hideName);
        STRATEGY.put(DesensitizeType.ID_CARD, DesensitizeUtil::hideIdCard);
        STRATEGY.put(DesensitizeType.EMAIL, DesensitizeUtil::hideEmail);
        STRATEGY.put(DesensitizeType.PHONE, DesensitizeUtil::hidePhone);
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
        if (value == null) {                // 1) 空值透传
            gen.writeNull();
            return;
        }

        if (type == DesensitizeType.CUSTOM) {
            gen.writeString(DesensitizeUtil.customMask(value, prefixLen, suffixLen, mask));
        } else {
            UnaryOperator<String> func = STRATEGY.get(type);
            if (func == null) {
                throw new IllegalArgumentException("未注册的策略：" + type);
            }
            gen.writeString(func.apply(value));
        }
    }

    /* 读取注解信息，构造专属序列化器 */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
            throws JsonMappingException {
        if (property != null && Objects.equals(property.getType().getRawClass(), String.class)) {
            Desensitize anno = property.getAnnotation(Desensitize.class);
            if (anno != null) {
                return new DesensitizeJsonSerializer(
                        anno.type(), anno.prefixNoMaskLen(), anno.suffixNoMaskLen(), anno.symbol());
            }
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}

